<template>
  <van-popup :show="visible" position="bottom" :style="{ height: '100%' }" :close-on-click-overlay="true"
    @update:show="handleUpdateShow" @close="handleClose" class="community-detail-popup">
    <div ref="detailContainer" class="community-detail" @touchstart="handleTouchStart" @touchmove="handleTouchMove"
      @touchend="handleTouchEnd">
      <div ref="cardWrapper" class="card-wrapper" :style="{
        transform: `translateY(${cardOffsetY}px)`,
        transition: isTransitioning ? 'transform 0.3s cubic-bezier(0.4, 0, 0.2, 1)' : 'none'
      }">
        <div v-if="previousItem" class="card-item card-prev" :key="`prev-${props.currentIndex - 1}`">
          <CommunityCardContent :item="previousItem" :show-info="false" />
        </div>

        <div class="card-item card-current" :key="`current-${props.currentIndex}`">
          <CommunityCardContent :item="currentItem" :show-info="showInfo" @toggle-info="toggleInfoVisibility"
            @close="handleClose" @video-play="handleVideoPlay" @video-pause="handleVideoPause"
            @photo-change="handlePhotoChange" />
        </div>

        <div v-if="nextItem" class="card-item card-next" :key="`next-${props.currentIndex + 1}`">
          <CommunityCardContent :item="nextItem" :show-info="false" />
        </div>
      </div>

      <div v-if="isLastItem && isLoadingMore" class="bottom-loading">
        <van-loading type="spinner" color="#1989fa" />
        <span class="loading-text">加载中...</span>
      </div>
    </div>
  </van-popup>
</template>

<script setup lang="ts">
import { ref, computed, watch, nextTick } from 'vue';
import { showNotify } from 'vant';
import CommunityCardContent from './CommunityCardContent.vue';

interface Props {
  visible: boolean; // 弹窗显示状态
  item: any; // 当前显示的卡片数据
  itemList?: any[]; // 卡片数据列表
  currentIndex?: number; // 当前卡片索引
  isLoadingMore?: boolean; // 是否正在加载更多数据
  hasMore?: boolean; // 是否还有更多数据
}

const props = withDefaults(defineProps<Props>(), {
  visible: false,
  item: null,
  itemList: () => [],
  currentIndex: 0,
  isLoadingMore: false,
  hasMore: true
});

const emit = defineEmits<{
  'update:visible': [value: boolean];
  'close': [];
  'item-change': [index: number];
  'load-more': [];
}>();

// UI状态
const showInfo = ref(true); // 是否显示底部信息栏
const detailContainer = ref<HTMLElement | null>(null); // 详情容器DOM引用
const cardWrapper = ref<HTMLElement | null>(null); // 卡片容器DOM引用

// 触摸滑动状态
const touchStartY = ref(0); // 触摸开始时的Y坐标
const touchStartX = ref(0); // 触摸开始时的X坐标
const touchStartTime = ref(0); // 触摸开始时间
const isSwiping = ref(false); // 是否正在滑动
const currentItemIndex = ref(0); // 当前卡片索引
const cardOffsetY = ref(0); // 卡片容器的Y轴偏移量
const isTransitioning = ref(false); // 是否正在执行切换动画

// 计算属性
const currentItem = computed(() => props.item); // 当前卡片数据

// 获取上一个卡片数据
const previousItem = computed(() => {
  const itemList = props.itemList || [];
  const index = props.currentIndex || 0;
  return index > 0 ? itemList[index - 1] : null;
});

// 获取下一个卡片数据
const nextItem = computed(() => {
  const itemList = props.itemList || [];
  const index = props.currentIndex || 0;
  return index < itemList.length - 1 ? itemList[index + 1] : null;
});

// 判断是否为最后一个卡片
const isLastItem = computed(() => {
  const itemList = props.itemList || [];
  const index = props.currentIndex || 0;
  return index >= itemList.length - 1;
});

// 处理弹窗显示状态更新
const handleUpdateShow = (value: boolean) => {
  emit('update:visible', value);
};

// 处理关闭弹窗
const handleClose = () => {
  emit('update:visible', false);
  emit('close');
};

// 切换信息栏显示/隐藏
const toggleInfoVisibility = () => {
  showInfo.value = !showInfo.value;
};

// 处理视频播放事件
const handleVideoPlay = () => {
};

// 处理视频暂停事件
const handleVideoPause = () => {
};

// 处理图片切换事件
const handlePhotoChange = (index: number) => {
};

// 处理触摸开始事件：记录触摸起始位置和时间
const handleTouchStart = (e: TouchEvent) => {
  if (!e.touches || e.touches.length === 0) return;
  const touch = e.touches[0];
  if (!touch) return;
  touchStartY.value = touch.clientY;
  touchStartX.value = touch.clientX;
  touchStartTime.value = Date.now();
  isSwiping.value = false;
};

// 处理触摸移动事件：实时更新卡片位置，跟随手指移动
const handleTouchMove = (e: TouchEvent) => {
  if (!touchStartY.value || !e.touches || e.touches.length === 0) return;
  const touch = e.touches[0];
  if (!touch) return;

  const currentY = touch.clientY; // 当前Y坐标
  const currentX = touch.clientX; // 当前X坐标
  const deltaY = currentY - touchStartY.value; // Y轴偏移量
  const deltaX = currentX - touchStartX.value; // X轴偏移量

  // 如果正在加载更多且是最后一个，禁止向上滑动（切换到下一个）
  if (props.isLoadingMore && isLastItem.value && deltaY < 0) {
    e.preventDefault();
    return;
  }

  // 判断是否为垂直滑动
  if (Math.abs(deltaY) > Math.abs(deltaX) && Math.abs(deltaY) > 10) {
    isSwiping.value = true;

    // 实时更新卡片位置
    if (!isTransitioning.value) {
      cardOffsetY.value = deltaY;
    }

    e.preventDefault();
  }
};

// 处理触摸结束事件：判断滑动距离和速度，决定是否切换卡片
const handleTouchEnd = (e: TouchEvent) => {
  if (!isSwiping.value || !touchStartY.value) {
    touchStartY.value = 0;
    touchStartX.value = 0;
    cardOffsetY.value = 0;
    return;
  }

  if (!e.changedTouches || e.changedTouches.length === 0) {
    touchStartY.value = 0;
    touchStartX.value = 0;
    cardOffsetY.value = 0;
    isSwiping.value = false;
    return;
  }

  const changedTouch = e.changedTouches[0];
  if (!changedTouch) {
    touchStartY.value = 0;
    touchStartX.value = 0;
    cardOffsetY.value = 0;
    isSwiping.value = false;
    return;
  }

  const endY = changedTouch.clientY; // 触摸结束Y坐标
  const deltaY = endY - touchStartY.value; // 总Y轴偏移量
  const deltaTime = Date.now() - touchStartTime.value; // 滑动耗时
  const containerHeight = detailContainer.value?.clientHeight || window.innerHeight; // 容器高度

  // 滑动阈值配置
  const minDistance = 80; // 最小滑动距离
  const fastSwipeDistance = 50; // 快速滑动最小距离
  const fastSwipeTime = 300; // 快速滑动最大时间
  const minDistanceRatio = containerHeight * 0.25; // 最小滑动距离比例

  // 判断是否满足切换条件
  if (
    Math.abs(deltaY) > minDistance || // 滑动距离超过最小阈值
    Math.abs(deltaY) > minDistanceRatio || // 滑动距离超过容器高度的25%
    (Math.abs(deltaY) > fastSwipeDistance && deltaTime < fastSwipeTime) // 滑动距离>50px且时间<300ms
  ) {
    if (deltaY < 0) {
      // 向上滑动：切换到下一个
      if (isLastItem.value && props.isLoadingMore) {
        cardOffsetY.value = 0;
        showNotify({
          type: 'warning',
          message: '数据正在加载中，请耐心等待哦~',
          duration: 2000
        });
        return;
      }
      switchToNextWithAnimation();
    } else {
      // 向下滑动：切换到上一个
      switchToPreviousWithAnimation();
    }
  } else {
    // 距离不够，回弹到原位置
    cardOffsetY.value = 0;
  }

  // 重置触摸状态
  touchStartY.value = 0;
  touchStartX.value = 0;
  isSwiping.value = false;
};

// 切换到下一个卡片：向上滑动整个容器，然后更新索引并重置位置
const switchToNextWithAnimation = () => {
  const itemList = props.itemList || [];
  currentItemIndex.value = props.currentIndex || 0;

  if (currentItemIndex.value < itemList.length - 1) {
    // 还有下一个，执行切换动画
    isTransitioning.value = true;
    const containerHeight = detailContainer.value?.clientHeight || window.innerHeight;

    // 向上滑动整个容器
    cardOffsetY.value = -containerHeight;

    setTimeout(() => {
      // 更新索引并通知父组件
      currentItemIndex.value++;
      emit('item-change', currentItemIndex.value);

      // 重置位置
      nextTick(() => {
        cardOffsetY.value = 0;
        isTransitioning.value = false;
      });
    }, 300);
  } else {
    // 已经是最后一个
    if (props.isLoadingMore) {
      // 如果正在加载，只回弹并显示提示
      cardOffsetY.value = 0;
      showNotify({
        type: 'warning',
        message: '数据正在加载中，请耐心等待哦~',
        duration: 2000
      });
    } else if (props.hasMore) {
      // 还有更多数据，触发加载更多
      cardOffsetY.value = 0;
      isTransitioning.value = true;
      setTimeout(() => {
        isTransitioning.value = false;
        emit('load-more');
      }, 200);
    } else {
      // 没有更多数据了，只回弹
      cardOffsetY.value = 0;
      isTransitioning.value = true;
      setTimeout(() => {
        isTransitioning.value = false;
      }, 200);
    }
  }
};

// 切换到上一个卡片：向下滑动整个容器，然后更新索引并重置位置
const switchToPreviousWithAnimation = () => {
  currentItemIndex.value = props.currentIndex || 0;

  if (currentItemIndex.value > 0) {
    isTransitioning.value = true;
    const containerHeight = detailContainer.value?.clientHeight || window.innerHeight;

    // 向下滑动整个容器
    cardOffsetY.value = containerHeight;

    setTimeout(() => {
      // 更新索引并通知父组件
      currentItemIndex.value--;
      emit('item-change', currentItemIndex.value);

      // 重置位置
      nextTick(() => {
        cardOffsetY.value = 0;
        isTransitioning.value = false;
      });
    }, 300);
  } else {
    // 已经是第一个，回弹
    cardOffsetY.value = 0;
    isTransitioning.value = true;
    setTimeout(() => {
      isTransitioning.value = false;
    }, 200);
  }
};

// 监听弹窗显示状态变化：打开时重置状态，关闭时清理
watch(
  () => props.visible,
  (newVal) => {
    if (newVal) {
      showInfo.value = true;
      currentItemIndex.value = props.currentIndex || 0;
      cardOffsetY.value = 0;
      isTransitioning.value = false;
    } else {
      cardOffsetY.value = 0;
      isTransitioning.value = false;
    }
  }
);

// 监听当前索引变化：同步内部状态并重置位置
watch(
  () => props.currentIndex,
  (newIndex) => {
    if (newIndex !== currentItemIndex.value) {
      currentItemIndex.value = newIndex || 0;
      cardOffsetY.value = 0;
      isTransitioning.value = false;
    }
  }
);

// 监听卡片数据变化：切换卡片时重置状态
watch(
  () => props.item,
  () => {
    showInfo.value = true;
    cardOffsetY.value = 0;
  },
  { deep: true }
);
</script>

<style scoped lang="less">
.community-detail-popup {
  background-color: #000;
}

.community-detail {
  width: 100%;
  height: 100vh;
  position: relative;
  background-color: #000;
  overflow: hidden;
  touch-action: pan-y;
  user-select: none;
}

.card-wrapper {
  width: 100%;
  position: relative;
  will-change: transform;
  height: 100vh;
}

.card-item {
  position: absolute;
  left: 0;
  width: 100%;
  height: 100vh;
  background-color: #000;

  &.card-prev {
    top: -100vh;
    z-index: 1;
  }

  &.card-current {
    top: 0;
    z-index: 2;
  }

  &.card-next {
    top: 100vh;
    z-index: 1;
  }
}

.bottom-loading {
  position: absolute;
  bottom: 100px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  z-index: 100;
  padding: 15px 25px;
  background-color: rgba(0, 0, 0, 0.6);
  border-radius: 20px;

  .loading-text {
    color: #fff;
    font-size: 12px;
  }
}
</style>
